package com.sghd.fight.module.facade;

import com.sghd.common.scheduler.ScheduledTask;
import com.sghd.common.scheduler.Scheduler;
import com.sghd.common.socket.anno.InSession;
import com.sghd.common.socket.anno.SocketCommand;
import com.sghd.common.socket.anno.SocketModule;
import com.sghd.fight.module.game.event.GameServerEvent;
import com.sghd.fight.module.game.service.GameService;
import com.sghd.fight.net.SocketEnum;
import com.sghd.fight.utils.Callback;
import com.sghd.pojo.fight.game.PlayerVo;
import com.sghd.pojo.fight.game.RsetSkillVo;
import com.sghd.pojo.fight.game.SettleVo;
import com.sghd.pojo.fight.game.Sn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;

import static com.sghd.common.socket.session.SessionKeys.MANAGEMENT;

/**
 * @author frank
 * @date 2018-12-03 15:15
 * @desc 接收大厅消息
 **/
@Component
@SocketModule
public class Receiver {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private GameService gameService;
    /** 大厅回调*/
    private ConcurrentMap<Long, Callback> callBacks = new ConcurrentHashMap<>();
    /** 序列号*/
    private AtomicLong sn = new AtomicLong();
    @Autowired
    private Scheduler scheduler;

    /**
     * 收到大厅结算信息执行回调
     * */
    @SocketCommand(SocketEnum.REQUEST_SETTLE)
    public void settle(@InSession(MANAGEMENT) String ip, SettleVo result) {
        long sn = result.getSn();
        Callback<Object> callback = removeBack(sn);
        if (callback == null) {
            logger.debug("回调函数已经被移除！", sn);
            return;
        }
        callback.call(result);
    }

    /**
     * 玩家基本信息
     * */
    @SocketCommand(SocketEnum.REQUEST_PLAYER_INFO)
    public void playerInfo(@InSession(MANAGEMENT) String ip, PlayerVo playerVo) {
        long sn = playerVo.getSn();
        Callback<Object> callback = removeBack(sn);
        if (callback == null) {
            logger.debug("回调函数已经被移除！", sn);
            return;
        }
        callback.call(playerVo);
    }

    /**
     * 收到重置技能回复
     * */
    @SocketCommand(SocketEnum.HALL_RESET_SKILL)
    public void resetSkill(@InSession(MANAGEMENT) String ip, RsetSkillVo rsetSkillVo) {
        long sn = rsetSkillVo.getSn();
        Callback<Object> callback = removeBack(sn);
        if (callback == null) {
            logger.debug("回调函数已经被移除！", sn);
            return;
        }
        callback.call(rsetSkillVo);
    }

    /**
     * 保存回调
     * @param roomId
     * @param call
     */
    public void saveBack(GameServerEvent event, Callback call) {
        Object body = event.getBody();
        if (!(body instanceof Sn)) {
            return;
        }
        Sn sn = (Sn) body;
        this.sn.compareAndSet(Long.MAX_VALUE, 0);
        sn.setSn(this.sn.getAndIncrement());
        callBacks.put(sn.getSn(), call);
        //请求大厅5秒超时
        scheduler.scheduleWithDelay(new ScheduledTask() {
            @Override
            public String getName() {
                return "POST:TIMEOUT";
            }

            @Override
            public void run() {
                Callback back = callBacks.remove(sn.getSn());
                if (back != null) {
                    back.onException(new TimeoutException(), null);
                }
            }
        }, 5000);
    }

    /**
     * 获取并移除房间的结算回调
     * @param sn
     * @return
     */
    public Callback removeBack(long sn) {
        return callBacks.remove(sn);
    }
}
